package com.thiswhyme.sentinel.server2.controller;

import com.thiswhyme.common.response.ResponseVo;
import com.thiswhyme.sentinel.server2.feign.UserFeign2Service;
import com.thiswhyme.sentinel.server2.feign.UserFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.CountDownLatch;

/**
 * feign demo
 * Created by thiswhyme on 2020/8/16.
 */
@RestController
@RequestMapping("/feign-demo/")
public class FeignDemoController {

    @Autowired
    private UserFeignService userFeignService;

    @Autowired
    private UserFeign2Service userFeign2Service;

    /**
     * feign_fallback-默认-demo
     * @param userId
     * @return
     */
    @GetMapping("user-name")
    public ResponseVo<String> queryUserName(@RequestParam Integer userId) {
        return userFeignService.queryUserName(userId);
    }

    /**
     * feign_fallback-自定义-demo
     * @param userId
     * @return
     */
    @GetMapping("user-name2")
    public ResponseVo<String> queryUserName2(@RequestParam Integer userId) {
        return userFeign2Service.queryUserName(userId);
    }

    /**
     * feign-方法熔断-demo
     * @param userId
     * @return
     */
    @GetMapping("user-name3")
    public ResponseVo<String> queryUserName3(@RequestParam Integer userId) throws InterruptedException {
        for (int t = 0; t < 20; t++) {
            CountDownLatch latch = new CountDownLatch(1);
            CountDownLatch await = new CountDownLatch(10);

            for (int i = 0; i < 10; i++) {
                int count = i;
                new Thread(() -> {
                    System.out.println("线程" + count + "正在等待主线程发布口令");
                    try {
                        latch.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("线程" + count + "已接受主线程口令");

                    ResponseVo<String> resp = userFeign2Service.queryUserName(userId);
                    System.out.println("方法熔断测试====================" + new SimpleDateFormat("yyyy-MM-dd 00:00:00").format(new Date()) + count + ": " + resp.getMsg());
                    System.out.println("线程" + count + "执行完成");
                    await.countDown();
                }).start();
            }

            Thread.sleep(100);
            latch.countDown();
            System.out.println(Thread.currentThread().getName() + "已发送第【" + t + "】波口令，正在等待所有线程执行完成");
            await.await();
            System.out.println("第【" + t + "】波口令，所有子线程执行完");
        }

        return ResponseVo.success();
    }

    /**
     * feign-ip:port熔断-demo
     * @param userId
     * @return
     */
    @GetMapping("user-name4")
    public ResponseVo<String> queryUserName4(@RequestParam Integer userId) throws InterruptedException {
        for (int t = 0; t < 20; t++) {
            CountDownLatch latch = new CountDownLatch(1);
            CountDownLatch await = new CountDownLatch(20);

            for (int i = 0; i < 20; i++) {
                int count = i;
                new Thread(() -> {
                    System.out.println("线程" + count + "正在等待主线程发布口令");
                    try {
                        latch.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("线程" + count + "已接受主线程口令");

                    ResponseVo<String> resp2 = userFeign2Service.queryUserName2(userId);
                    System.out.println("ip:port熔断测试====================" + new SimpleDateFormat("yyyy-MM-dd 00:00:00").format(new Date()) + count + ": " + resp2.getMsg());
                    System.out.println("线程" + count + "执行完成");
                    await.countDown();
                }).start();
            }

            Thread.sleep(100);
            latch.countDown();
            System.out.println(Thread.currentThread().getName() + "已发送第【" + t + "】波口令，正在等待所有线程执行完成");
            await.await();
            System.out.println("第【" + t + "】波口令，所有子线程执行完");
        }

        return ResponseVo.success();
    }

    /**
     * feign-serviceId熔断-demo
     * @param userId
     * @return
     */
    @GetMapping("user-name5")
    public ResponseVo<String> queryUserName5(@RequestParam Integer userId) throws InterruptedException {
        for (int t = 0; t < 20; t++) {
            CountDownLatch latch = new CountDownLatch(1);
            CountDownLatch await = new CountDownLatch(10);

            for (int i = 0; i < 10; i++) {
                int count = i;
                new Thread(() -> {
                    System.out.println("线程" + count + "正在等待主线程发布口令");
                    try {
                        latch.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("线程" + count + "已接受主线程口令");

                    ResponseVo<String> resp3 = userFeign2Service.queryUserName3(userId);
                    System.out.println("serviceId熔断测试====================" + new SimpleDateFormat("yyyy-MM-dd 00:00:00").format(new Date()) + count + ": " + resp3.getMsg());
                    System.out.println("线程" + count + "执行完成");
                    await.countDown();
                }).start();
            }

            Thread.sleep(100);
            latch.countDown();
            System.out.println(Thread.currentThread().getName() + "已发送第【" + t + "】波口令，正在等待所有线程执行完成");
            await.await();
            System.out.println("第【" + t + "】波口令，所有子线程执行完");
        }

        return ResponseVo.success();
    }

    /**
     * feign-熔断综合-demo
     * @param userId
     * @return
     */
    @GetMapping("user-name6")
    public ResponseVo<String> queryUserName6(@RequestParam Integer userId) throws InterruptedException {
        for (int t = 0; t < 20; t++) {
            CountDownLatch latch = new CountDownLatch(1);
            CountDownLatch await = new CountDownLatch(5);

            for (int i = 0; i < 5; i++) {
                int count = i;
                new Thread(() -> {
                    System.out.println("线程" + count + "正在等待主线程发布口令");
                    try {
                        latch.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("线程" + count + "已接受主线程口令");

                    ResponseVo<String> resp = userFeign2Service.queryUserName(userId);
                    ResponseVo<String> resp2 = userFeign2Service.queryUserName2(userId);
                    ResponseVo<String> resp3 = userFeign2Service.queryUserName3(userId);
                    System.out.println("方法熔断测试====================" + new SimpleDateFormat("yyyy-MM-dd 00:00:00").format(new Date()) + count + ": " + resp.getMsg());
                    System.out.println("ip:port熔断测试====================" + new SimpleDateFormat("yyyy-MM-dd 00:00:00").format(new Date()) + count + ": " + resp2.getMsg());
                    System.out.println("serviceId熔断测试====================" + new SimpleDateFormat("yyyy-MM-dd 00:00:00").format(new Date()) + count + ": " + resp3.getMsg());
                    System.out.println("线程" + count + "执行完成");
                    await.countDown();
                }).start();
            }

            Thread.sleep(100);
            latch.countDown();
            System.out.println(Thread.currentThread().getName() + "已发送第【" + t + "】波口令，正在等待所有线程执行完成");
            await.await();
            System.out.println("第【" + t + "】波口令，所有子线程执行完");
        }

        return ResponseVo.success();
    }
}
